package com.soxing.webrain.brush.controller;


import com.jmatio.io.MatFileReader;
import com.jmatio.types.*;
import com.mathworks.toolbox.javabuilder.*;
import com.soxing.webrain.brush.api.IUserEegHandleService;
import com.soxing.webrain.brush.api.zip.IReadZipStructService;
import com.soxing.webrain.brush.common.util.AddressDesUtil;
import com.soxing.webrain.brush.dao.service.ICombsUserFileService;
import com.soxing.webrain.brush.dao.service.ICombsUserUploadFileService;
import com.soxing.webrain.brush.domain.view.Eeg;
import com.soxing.webrain.brush.domain.view.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import wb_loadEEG.WbPopLoadSet;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

//http://localhost:18081/myview/view
//@RestController
//@RequestMapping("/myview")
@Slf4j
@RestController("/myView")     //restControlller路径上可以不用写myview
@Api(value = "画图管理", tags = {"画图管理"})
public class MyViewController {

    @Resource
    private ICombsUserFileService userFileService;
    @Resource
    private ICombsUserUploadFileService userUploadFileService;
    @Resource
    private IUserEegHandleService userEegHandleService;
    @Resource
    private IReadZipStructService readZipStructService;

    @GetMapping("/view")
    @ApiOperation(value = "Eeg数据读取")
    public Eeg getIdFileList(@RequestParam(value = "fullpath", required = false) String fullpath, @RequestParam(value = "star", required = false) Integer star,
                             @RequestParam(value = "end", required = false) Integer end, HttpServletRequest request) {
        if (fullpath == "0") {
            return null;
        }

        String path = AddressDesUtil.getDecryptString(fullpath);
        return userEegHandleService.packageData(star, end, path);
    }

    @GetMapping("/view1")
    public String myFirst()
    {

        return "hello";

    }
    @GetMapping("2d")
    public R get2d()
    {

        String EEGfile = "D:\\matlab\\webrain_download\\4002-power2\\power_sub001.mat";
        File f = new File(EEGfile);
        MatFileReader reader = null;
        try {
            reader = new MatFileReader(f);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 文件中只有一个 1*1 的 struct, name = "EEG_results"
        MLStructure EEG_results = (MLStructure) reader.getContent().get("EEG_results");
        String type = EEG_results.getField("type").contentToString();
        String filename = EEG_results.getField("filename").contentToString();

        MLStructure parameter = (MLStructure)EEG_results.getField("parameter");
        MLCell bandname = (MLCell)parameter.getField("bandName");
        int[] bandname_numbers = bandname.getDimensions();
        int bandname_number = bandname_numbers[0];
        String[] bandname_data = new String[bandname_number];
        for(int i =0;i<bandname_number;i++)
        {
            MLChar bandname1 = (MLChar) bandname.get(i);
            bandname_data[i] = bandname1.getString(0);

        }

        MLStructure chanlocs = (MLStructure)parameter.getField("chanlocs");
        int[] dimensions = chanlocs.getDimensions();
        int dimension = dimensions[1];
        double[] test = new double[dimension];


        int record_bad = 0;
        for(int i = 0;i<dimension;i++)
        {
            try{
                MLDouble theta = (MLDouble) chanlocs.getField("theta", i);
                double[][] theta_f = theta.getArray();
                test[i] = theta_f[0][0];

            }catch (Exception e)
            {
                record_bad++;
            }
        }

        double[] theta_data = new double[dimension-record_bad];
        double[] radius_data = new double[dimension-record_bad];
        String[] labels_data = new String[dimension-record_bad];

        int bad = 0; //记录不是脑电的导联的数量
        int[] record = new int[dimension];//记录一下非头皮的导联 如果不是就标号为一
        for(int i=0;i<dimension;i++)
        {
            try {//有的导联是眼电或者是心电这里的 所以要写一下逻辑

                MLDouble theta = (MLDouble) chanlocs.getField("theta", i);
                double[][] theta_f = theta.getArray();
                theta_data[i-bad] = theta_f[0][0];

                MLDouble radius = (MLDouble) chanlocs.getField("radius", i);
                double[][] radius_f = radius.getArray();
                radius_data[i-bad] = radius_f[0][0];

                MLChar label = (MLChar) chanlocs.getField("labels", i);
                labels_data[i-bad] = label.getString(0);
            }catch(Exception e)
            {

                record[i] = 1;
                bad++;
            }
        }

        MLDouble tmp = (MLDouble)EEG_results.getField("Power_relative_mean");
        double[][] Power_relative_mean = (tmp.getArray());
        int time = Power_relative_mean[0].length;
        double[][] power_data = new double[dimension-bad][time];

//        double[] theta_data_f = new double[dimension-bad];
//        double[] radius_data_f = new double[dimension-bad];
//        String[] labels_data_f = new String[dimension-bad];
//        double[][] power_data_f = new double[dimension-bad][];
        int record_number=0;
        for(int i =0;i<dimension;i++)
        {
            if (record[i] ==1)
            {
                record_number++;
                continue;
            }

            for(int j=0; j<time;j++)
            {
                power_data[i-record_number][j] = Power_relative_mean[i][j];
            }
        }

//        System.out.println("文件类型： " + type);
//        System.out.println("文件名字： " + filename);
//        System.out.println("数组维度:  " + Power_relative_mean.length + " * " + Power_relative_mean[0].length);
//        System.out.println(Power_relative_mean[1][1]);

        return R.ok().data("power_mean",Power_relative_mean).data("theta",theta_data).data("radius",radius_data).data("bandName",bandname_data).data("labels",labels_data);

    }


    //这个是原来的3d可视化用的，实打实加载溯源结果文件的
    @GetMapping("getData")
    public R getData()
    {
        int trial = 43;  //总共的trial数
        int times = 2500;  //总共的times数
        int user_trial = 1;//用户指定的trials具体是多少
        int user_times = 0;//用户指定的times数具体是多少
        float[] myData = new float[6144];
        float[] vTrialData = new float[times];   //某一个tials平均的数据
        WbPopLoadSet w = null;
        Object[] result = null;
        try {

            System.out.println("解析开始");

            w = new WbPopLoadSet();
            result = w.wb_loadEEG(18, "D:\\matlab\\output\\new_source");

            MWNumericArray temp = (MWNumericArray) result[1];

            float[][] data1 = (float[][]) temp.toFloatArray();
            //加载顺序是先从第二纬度开始加载的 第二个纬度完一遍开始 第三纬度加一
            //6144*times*trials大概的顺序是这样的
            MWArray.disposeArray(temp);

            int wave_dot = 0;
            for(wave_dot=0;wave_dot<times;wave_dot++)
            {

                int D_dot = 0;
                vTrialData[wave_dot] = 0;
                for(D_dot = 0;D_dot<6144;D_dot++)
                {
                    vTrialData[wave_dot] +=data1[D_dot][user_trial*times+wave_dot];

                }
                vTrialData[wave_dot] = vTrialData[wave_dot]/(float)(6144.0);
                //System.out.println(vTrialData[wave_dot]);

            }

            int dot = 0;
            for(dot = 0;dot<6144;dot++)
            {


                myData[dot] = data1[dot][user_trial*times+user_times];
            }


//            System.out.println(data1[0][0]);
//            System.out.println(data1[0][1]);


        }catch (MWException e) {
            e.printStackTrace();
        }finally{
            MWArray.disposeArray(result);
        }

        System.out.println("解析结束");
        return R.ok().data("data",myData).data("wave",vTrialData);
    }

    @GetMapping("getData1")
    public R getData1()
    {

        //float[] myData = new float[6144];
        float[] vTrialData = new float[2500];   //某一个tials平均的数据


        System.out.println("解析结束");
        Random random = new Random();
        return R.ok().data("data",readMat1("now"+ (random.nextInt(7)+1)+".mat")).data("wave",vTrialData);
    }

    public float[] readMat1(String fileName){
        String EEGfile = "D:\\matlab\\output\\mat\\"+fileName;
        float[] result;
        File f = new File(EEGfile);
        MatFileReader reader = null;
        try {
            reader = new MatFileReader(f);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();
        MLArray mlArray=reader.getMLArray(fileName.split("\\.")[0]);
        MLSingle d=(MLSingle)mlArray;
        final int[] dimensions = d.getDimensions();
        float[] record = new float[dimensions[0]];
        result = record;
        for(int i=0;i<dimensions[0];i++){
            record[i] = d.get(i);
        }

        return result;
        //System.out.println();

    }



    @GetMapping("test")
    public R Test(@RequestParam(value = "star", required = false) Integer star,
                  @RequestParam(value = "end", required = false) Integer end)
    {


        int starttime = star;
        int endtime = end;
        System.out.println(endtime);
        String EEGfile = "";
        WbPopLoadSet w = null;
        Eeg eeg = new Eeg();
//        int indexUnzip = EEGfile.indexOf("/");
//        for (int i = 0; i < 4; i ++) {
//            indexUnzip = EEGfile.indexOf('/',indexUnzip + 1);
//        }
//
//        String tmpdir = EEGfile.substring(indexUnzip + 1);
//        tmpdir = StringUtils.substringBeforeLast((systemConfig.getBeforeUnzip() + tmpdir), "/") + "/unzip";
//
//        // 不存在就创建一个解压文件夹
//        File unzip = new File(tmpdir);
//        if (!unzip.exists()) {
//            unzip.mkdir();
//        }

        String unzip_dir = "D:\\matlab\\test\\example\\EGI\\output\\e84as5_RestCloseOpen_EEG";
        unzip_dir = "D:\\matlab\\test\\example\\BP\\output\\e8fajs_CompareNumber_EEG\\1";
        //unzip_dir = "D:\\matlab\\test\\example\\boruikang\\output\\e84as5_E202112301506504932_EEG";


        try {
            w = new WbPopLoadSet();
        } catch (MWException e) {
            e.printStackTrace();
        }
        Object[] result = null;

        try {
            result = w.wb_loadEEG(18, unzip_dir);

        MWNumericArray temp = (MWNumericArray) result[1];
        double[][] data = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[2];
        double[][] srate = (double[][]) temp.toDoubleArray();

        String ref = (String) result[3].toString();

        MWCellArray temp1 = (MWCellArray) result[4];
        String event_type = temp1.toString();

        temp = (MWNumericArray) result[5];
        double[][] event_latency = (double[][]) temp.toDoubleArray();

        MWCharArray temp2 = (MWCharArray) result[6];
        String labels = (String) temp2.toString();

        temp = (MWNumericArray) result[7];
        double[][] sph_radius = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[8];
        double[][] sph_theta = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[9];
        double[][] phi = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[10];
        double[][] theta = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[11];
        double[][] radius = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[15];
        double[][] xmin = (double[][]) temp.toDoubleArray();

        temp = (MWNumericArray) result[16];
        double[][] xmax = (double[][]) temp.toDoubleArray();

            //0. ---------------- 定义数据存储的对象



            //2. ----------------- data 数据处理

            List<List<Double>> groupdata = new ArrayList<List<Double>>();
            for (int i = 0; i < data.length; i++) {
                List datas = new ArrayList();
                int s = (int) (1000 / srate[0][0]);
                for (int j = (int) (starttime * srate[0][0]); j < endtime * srate[0][0]; j++) {
                    if (j == data[0].length) {
                        break;
                    } else {
                        datas.add(data[i][j]);
                    }

                }
                groupdata.add(datas);
            }

            //3. ----------------- labels(数据chanlocs可能不存在 分开分析) 数据处理


            List<String> grouplabel = new ArrayList();
            if (labels != null) {
                grouplabel = formatData(labels);
            } else {
                for (int i = 1; i < data.length; i++) {
                    grouplabel.add(i + "");
                }
            }


            //4.---------------- event_type(两种类型字符串或者数组) 数据处理

            if (event_type.contains("[")) {
                String[] tp = event_type.split("[\\[\\]]");
                //------- 对label进行整理  定义集合
                List<String> tp1 = new ArrayList();
                for (int i = 0, j = 0; i < tp.length; i++) {
                    if (i % 2 != 0) {
                        tp1.add(tp[i]);
                    }
                }
                eeg.setEvent_type(tp1);

            } else {

                String[] tp = event_type.split("'"); //la的长度为 labels的二倍
                List<String> tp1 = new ArrayList(); //定义一个用于存放
                for (int i = 1, index = 0; i < tp.length; index++) {
                    tp1.add(tp[i]);
                    i = i + 2;
                }
                eeg.setEvent_type(tp1);
            }

            //5. ---------------- event_latency 标线时间点 数据处理

            //5.1 --------------- event_latency 为空判断
            double[] evtls = null;
            if (event_latency.length != 0) {
                evtls = event_latency[0];
            }else {
                evtls = new double[]{1};
            }


            //6. ---------------- srate 数据处理
            double[] sraten = srate[0];


            //7. ---------------- 电极坐标theta radius的数值  数据处理

            //7.1 --------------- theta 判空
            double[] thetan = null;
            if (theta.length != 0) {
                thetan = theta[0];
            }

            //7.2 ---------------- radius 判空
            double[] radiusn = null;
            if (radius.length != 0) {
                radiusn = radius[0];
            }


            //8. -------------------- 最小值（判断是erp数据还是eeg数据）
            double[] xminn = xmin[0];

            //9. -------------------- 最大值
            double[] xmaxn = xmax[0];

            //10. -------------------- time（传输starttime 和 endtime）数据处理
            List time = new ArrayList();
            for (int i = 0; i <= 5 * srate[0][0]; i++) {
                time.add(starttime + 0.001 * i * 1000 / srate[0][0]);
            }

            // ============== 数据存储
            eeg.setData(groupdata);

            eeg.setSrate(sraten);
            eeg.setRef(ref);
            eeg.setEvent_latency(evtls);
            eeg.setLabels(grouplabel);
            eeg.setTheta(thetan);
            eeg.setRadius(radiusn);
            eeg.setXmin(xminn);
            eeg.setXmax(xmaxn);
            eeg.setTime(time);


        } catch (MWException e) {
            e.printStackTrace();

        }finally{
            MWArray.disposeArray(result);
        }




        return R.ok().data("eeg",eeg);
    }
    public List<String> formatData(String labels) {

        String[] la = labels.split("\n"); //la的长度为 labels的二倍
        List<String> grouplabel = new ArrayList(); //定义一个用于存放
        for (int index = 0; index < la.length; index++) {
            grouplabel.add(la[index]);
            //i = i + 2;
        }
        return grouplabel;
    }
}
